/*
Copyright (c) 2008, Mike Gashler

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef __GHTTP_H__
#define __GHTTP_H__

#include <time.h>

class GHttpClientSocket;
class GSocketServer;
class GPointerArray;
class GHttpServerBuffer;
class GQueue;
class GHeap;
class GConstStringHashTable;


// This class allows you to get files using the HTTP protocol
class GHttpClient
{
public:
	enum Status
	{
		Downloading,
		Error,
		NotFound,
		Done,
		Aborted,
	};

protected:
	char m_szHeaderBuf[258];
	char m_szServer[256];
	char m_szClientName[32];
	int m_nHeaderPos;
	int m_nContentSize;
	bool m_bChunked;
	bool m_aborted;
	unsigned char* m_pData;
	int m_nDataPos;
	GHttpClientSocket* m_pSocket;
	Status m_status;
	GQueue* m_pChunkQueue;
	bool m_bPastHeader;
	char* m_szRedirect;
	time_t m_lastReceiveTime;
	char caLastModifiedString[60];
	bool m_bAmCurrentlyDoingJustHeaders;

public:
	GHttpClient();
	virtual ~GHttpClient();

	virtual void OnReceiveData(const unsigned char* pData, int nLen) {}

	// Send a request to get a file.  Returns immediately (before the file
	// is downloaded).
	bool Get(const char* szUrl, bool actuallyDownloadTheData = true);

	// See what the status of the download is.  If everything is going okay,
	// it will return "Downloading" while downloading and "Done" when the file
	// is available.  pfProgress is an optional parameter.  If it is non-NULL,
	// it will return a number between 0 and 1 that indicates the ratio of
	// content (not including header data) already downloaded.
	Status CheckStatus(float* pfProgress);

	// Don't call this until the status is "Done".  It returns a pointer to the
	// file that was downloaded.  The buffer will be deleted when this object is
	// deleted, so if you want to retain the buffer, call DropData instead.
	unsigned char* GetData(int* pnSize);
	//get the date string of this 
	char* GetUrlModified() { /* todor check first */ return caLastModifiedString; }

	// Just like GetData except it forgets about the buffer so you'll have to
	// delete it yourself.
	unsigned char* DropData(int* pnSize);
	


	// This is called when the connection is lost
	void OnLoseConnection();

	void SetClientName(const char* szClientName);
	
	void Abort();	// called by the consumer, when an abort is desired. 

protected:

	void ProcessHeader(const unsigned char* szData, int nSize);
	void ProcessBody(const unsigned char* szData, int nSize);
	void ProcessChunkBody(const unsigned char* szData, int nSize);
	void GimmeWhatYouGot();

};


#endif // __GHTTP_H__
